package cn.pku.sirx.snad.uias.analyzer.similarity;

import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;

import cn.pku.sirx.snad.uias.dao.ISchoolDao;
import cn.pku.sirx.snad.uias.model.entity.School;
import cn.pku.sirx.snad.uias.model.entity.SiteUser;
import cn.pku.sirx.snad.uias.util.AnalyzerUtils;

/**
 * @author WangXiao
 */
public class SchoolAndProfessionAnalyzer implements ISimilarityAnalyzer {

	@Override
	public int analyze(SiteUser fromUser, SiteUser toUser) {
		Assert.notNull(fromUser);
		Assert.notNull(toUser);

		Map<Integer, List<School>> fromSchoolMap = schoolDao
				.getByUserId(fromUser.getId());
		Map<Integer, List<School>> toSchoolMap = schoolDao.getByUserId(toUser
				.getId());
		return analyzeSchool(fromSchoolMap, toSchoolMap)
				+ analyzeProfession(fromSchoolMap, toSchoolMap);
	}

	private int analyzeSchool(Map<Integer, List<School>> fromSchoolMap,
			Map<Integer, List<School>> toSchoolMap) {
		int result = 0;
		for (Integer type : fromSchoolMap.keySet()) {
			List<School> toSchools = toSchoolMap.get(type);
			if (toSchools != null) {
				List<School> fromSchools = fromSchoolMap.get(type);
				result += AnalyzerUtils.getCommonCount(fromSchools, toSchools,
						SCHOOL_COMPARATOR);
			}
		}
		return result;
	}

	private int analyzeProfession(Map<Integer, List<School>> fromSchoolMap,
			Map<Integer, List<School>> toSchoolMap) {
		int result = 0;
		List<School> fromUniversities = fromSchoolMap
				.get(ISchoolDao.UNIVERSITY);
		if (fromUniversities != null) {
			List<School> toUniversities = toSchoolMap
					.get(ISchoolDao.UNIVERSITY);
			if (toUniversities != null) {
				// get same professions
				result += AnalyzerUtils.getCommonCount(fromUniversities,
						toUniversities, PROFESSION_COMPARATOR);
			}
		}
		return result;
	}

	private final Comparator<School> SCHOOL_COMPARATOR = new Comparator<School>() {

		@Override
		public int compare(School o1, School o2) {
			Assert.notNull(o1);
			Assert.notNull(o2);

			if (o1.getSchoolName() == null) {
				return Integer.MIN_VALUE;
			}
			if (o2.getSchoolName() == null) {
				return Integer.MAX_VALUE;
			}
			return o1.getSchoolName().compareTo(o2.getSchoolName());
		}

	};

	private final Comparator<School> PROFESSION_COMPARATOR = new Comparator<School>() {

		@Override
		public int compare(School o1, School o2) {
			Assert.notNull(o1);
			Assert.notNull(o2);

			if (o1.getDepartment() == null) {
				return Integer.MIN_VALUE;
			}
			if (o2.getDepartment() == null) {
				return Integer.MAX_VALUE;
			}
			return o1.getDepartment().compareTo(o2.getDepartment());
		}

	};

	private ISchoolDao schoolDao;

	public void setSchoolDao(ISchoolDao schoolDao) {
		this.schoolDao = schoolDao;
	}

}
